/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-09     WangJing       the first version
 */
#include "user_thread.h"
#include <rtdevice.h>
#include "user_config.h"
#include "led.h"
#include "robot_arm.h"
#include "pharmacy.h"
#include "lcd_spi_154.h"
#include "yolo.h"
#include "conveyor.h"
#include "platform2D.h"

#define DBG_TAG "User"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

// 定义线程句柄
rt_thread_t rt_thread_t_led = NULL;
rt_thread_t rt_thread_t_lcd = NULL;
rt_thread_t rt_thread_t_pi = NULL;
rt_thread_t rt_thread_t_arm1 = NULL;
rt_thread_t rt_thread_t_arm2 = NULL;
rt_thread_t rt_thread_t_pharmacy = NULL;
rt_thread_t rt_thread_t_key = NULL;

// 信号量
struct rt_semaphore rt_semaphore_pi = {0};

// 全局变量
volatile int PharmacyData[PHARMACY_NUM][MEDICINE_NUM] = {{0}};
volatile YoloData_t YoloData = {0};
volatile int FinishGoods[MEDICINE_NUM] = {0};
volatile int SumNum = 0;

#if ROBOT2_DEBUG == 1 || ROBOT1_DEBUG == 1
int PageNum = 2;
#else
int PageNum = 1;
#endif

//调试初始位置
//float ROBOT_DBG[3] = {0,200,230};

#if ROBOT2_DEBUG == 1
float ROBOT_DBG[3] = {-180,30,440};
int site = 0;
#endif

#if ROBOT1_DEBUG == 1
float ROBOT_DBG[3] = {0,130,130};
int site = 0;
#endif

// 线程初始化函数
void thread_init(void * p){

    // 初始化各个模块
    led_init();
    key_init();
    SPI_LCD_Init();
    ARM1_serial_init();
    ARM2_serial_init();
    LoRa_serial_init();
    Pi_serial_init();
    Platform2D_serial_init();
    conveyor_init();

    /* 初始化信号量 */
    rt_sem_init(&rt_semaphore_pi, "rt_semaphore_pi", 0, RT_IPC_FLAG_FIFO);

    // 创建并启动LED线程
    rt_thread_t_led = rt_thread_create("thread_led", thread_led, NULL, 1024, 15, 10);
    rt_thread_startup(rt_thread_t_led);

    // 创建并启动LCD线程
//    rt_thread_t_lcd = rt_thread_create("thread_lcd", thread_lcd, NULL, 1024, 15, 10);
//    rt_thread_startup(rt_thread_t_lcd);

    // 创建并启动Pi线程
//    rt_thread_t_pi = rt_thread_create("thread_pi", thread_pi, NULL, 2048, 16, 10);
//    rt_thread_startup(rt_thread_t_pi);

    // 创建并启动ARM1线程
    rt_thread_t_arm1 = rt_thread_create("thread_arm1", thread_arm1, NULL, 2048, 16, 10);
    rt_thread_startup(rt_thread_t_arm1);

    // 创建并启动ARM2线程
    rt_thread_t_arm2 = rt_thread_create("thread_arm2", thread_arm2, NULL, 2048, 16, 10);
    rt_thread_startup(rt_thread_t_arm2);

    // 创建并启动Pharmacy线程
    rt_thread_t_pharmacy = rt_thread_create("thread_pharmacy", thread_pharmacy, NULL, 2048, 16, 10);
    rt_thread_startup(rt_thread_t_pharmacy);

    // 创建并启动Key线程
//    rt_thread_t_key = rt_thread_create("thread_key", thread_key, NULL, 2048, 16, 10);
//    rt_thread_startup(rt_thread_t_key);

    LOG_D("INIT OK!!!");

}

void thread_pi(void * p){
    LOG_D("Start PI!!!");
    while(1){
        rt_sem_control(&rt_semaphore_pi, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&rt_semaphore_pi, RT_WAITING_FOREVER);  // 等待信号量
        YoloData = yolo_dataParser(Pi_GetBeffer(),1); //获取数据
    }
}

// Key线程函数，处理按键操作
void thread_key(void * p){
    LOG_D("Start KEY!!!");
#if ROBOT2_DEBUG == 1 ||  ROBOT1_DEBUG == 1
    while(1){

        if(0 == key_scan(2, 0)){
            while(0 == key_scan(2, 0))rt_thread_delay(10);
            ROBOT_DBG[site] += 10;
        }
        if(0 == key_scan(2, 1)){
            while(0 == key_scan(2, 1))rt_thread_delay(10);
            ROBOT_DBG[site] -= 10;
        }
        if(0 == key_scan(2, 2)){
            while(0 == key_scan(2, 2))rt_thread_delay(10);
            site = site >= 2 ? 0 : site + 1;
        }
        if(0 == key_scan(2, 3)){
            while(0 == key_scan(2, 3))rt_thread_delay(10);
            site = site <= 0 ? 2 : site - 1;
        }

        rt_thread_delay(100);
    }
#endif

    while(1){
        if(key_scan(2,1) == 0){
            while(key_scan(2,1) == 0)rt_thread_delay(10);
            PageNum ^= 1;  // 切换页面
        }
        rt_thread_delay(100);
    }
}

// Pharmacy线程函数，处理药房数据
void thread_pharmacy(void * p){
//    char dataPack1[] = "{0:ABHI}";  // 测试用数据包1
//    char dataPack2[] = "{1:ACK}";  // 测试用数据包2
//    char * pData[2];
//    pData[0] = dataPack1;
//    pData[1] = dataPack2;
//    int count = 0;
    LOG_D("Start Pharmacy!");
    while(1){
        // 处理药房数据
        if(0 == pharmacy_data_process((int (*)[MEDICINE_NUM])PharmacyData,(char*)LoRa_GetBeffer(),1)){
            LoRa_Transmit((uint8_t*)"Data OK!", sizeof("Data OK!"));
        }

//        if(0 != dataProcessFlag){
//            LOG_W("Error Code:%d",dataProcessFlag);
//        }
//        pharmacy_prescription_show(PharmacyData);
//
//        rt_kprintf("  ");
//        for(int i=0;i<MEDICINE_NUM;i++){
//            rt_kprintf(" %d ",PharmacyData[0][i] + PharmacyData[1][i]);
//        }
//        rt_kprintf("\n");

        rt_thread_delay(100);
//        count++;
    }
}

// 分拣机械臂线程
void thread_arm2(void * p){
    YoloData_t yoloData = {0};
    RobotArmRun_t robotArmRun = {0};
    float min_out = -70;  // 机械臂能到达的最初位置
    float max_out = 140;  // 机械臂能到达的最终位置
    float min_in = 0;  // 树莓派所给的最小坐标
    float max_in = 640;  // 树莓派所给的最大坐标

    int set = 0;  // 分类位置
    int setMin = 0;  // 分类药品中间变量，用于最终判断是哪一间药房的某类药
    char kind = '\0';  // 识别到的药品类

    LOG_D("Start ARM2!!!");

    while(strncmp("{PI OK!}",(char*)Pi_GetBeffer(),sizeof("{PI OK!}")-1)){  // 等待树莓派运行
        LOG_W("%s",Pi_GetBeffer());
        rt_thread_delay(1000);
    };
    LOG_W("Pi OK");

    robotArm_init(0);

    key_KA(0,0);  // 关闭吸泵
    conveyor_power(-1,1);  // 打开所有pwm

#if ROBOT2_YOLO_DEBUG == 1
    while(1){
        yoloData.y = yoloData.y >= 320 ? 0 : yoloData.y + 10;
        robotArmRun = robotArm_assign(min_out + (max_out - min_out) * (yoloData.y - min_in) / (max_in - min_in),330,240,ARM2_RUN_SPEED,1);  // 寻物位置
        robotArm_actionGroup(0,&robotArmRun,1);
        rt_thread_delay(100);
    }
#endif

#if ROBOT2_DEBUG == 1
    while(1){

        // 到1号放药位置
        robotArmRun = robotArm_assign(ROBOT_DBG[0],ROBOT_DBG[1],ROBOT_DBG[2],ARM2_RUN_SPEED,1);
        robotArm_actionGroup(0,&robotArmRun,1);

        rt_thread_delay(100);

    }
#endif

    // 抓取识别位置 0,330,240
    // 1号小车下货最终位置 180,30,440
    // 2号小车下货最终位置 -180,30,440
    float ARM2_LOOK_HIGH = 310;
    while(1){

        rt_thread_delay(1000); //启动前等待一下

        robotArmRun = robotArm_assign(0,330,ARM2_LOOK_HIGH,ARM2_RUN_SPEED,1);  // 举起
        robotArm_actionGroup(0,&robotArmRun,1);

        LOG_D("等待数据");

        conveyor_duty(0,PWM1_DUTY); // 启动传送带
        conveyor_duty(1,PWM2_DUTY);

        setMin = INVALID_MAX_VALUE;  // 初始化一个不可能的药品类
        set = 0;

        rt_sem_control(&rt_semaphore_pi, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&rt_semaphore_pi, RT_WAITING_FOREVER);  // 等待信号量
        LOG_E("%s",Pi_GetBeffer());
        yoloData = yolo_dataParser(Pi_GetBeffer(),1); //获取数据
        if(yoloData.kind == '\0') // 获取错误数据跳过本次
            continue;
        LOG_W("kind:%c  X:%d  Y:%d  ",yoloData.kind,yoloData.x,yoloData.y);

        robotArmRun = robotArm_assign(min_out + (max_out - min_out) * (yoloData.y - min_in) / (max_in - min_in),330,ARM2_LOOK_HIGH,ARM2_RUN_SPEED,1);  // 寻物位置
        robotArm_actionGroup(0,&robotArmRun,1);

        if(yoloData.x < 200)
            rt_thread_delay(500); // 大概运行到中间位置
        conveyor_duty(0,10);  // 传送带停止
        conveyor_duty(1,10);

        rt_thread_delay(1000); // 到中间位置停下来
        rt_sem_control(&rt_semaphore_pi, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&rt_semaphore_pi, RT_WAITING_FOREVER);  // 等待信号量

        yoloData = yolo_dataParser(Pi_GetBeffer(),1); //获取数据
        kind = yoloData.kind;

        robotArmRun = robotArm_assign(min_out + (max_out - min_out) * (yoloData.y - min_in) / (max_in - min_in),330,ARM2_LOOK_HIGH,ARM2_RUN_SPEED,1);  // 寻物位置
        robotArm_actionGroup(0,&robotArmRun,1);

        conveyor_duty(0,PWM1_DUTY); // 启动传送带
        conveyor_duty(1,PWM2_DUTY);

        LOG_W("kind:%c  X:%d  Y:%d  ",yoloData.kind,yoloData.x,yoloData.y);

        LOG_E("ScanKind:%c",kind);

        while(!(0 == key_scan(0, 3)))
            rt_thread_delay(100);

        conveyor_duty(0,10); // 停止传送带
        conveyor_duty(1,10);

        // 得到此次分拣的位置，按优先完成原则
        for(int i=0;i<PHARMACY_NUM;i++){  // 遍历每个药房
            if(setMin > PharmacyData[i][kind-'A'] && PharmacyData[i][kind-'A'] != 0){  // 判断
                setMin = PharmacyData[i][kind-'A'];
                set = i;
            }
        }
        LOG_D("setMin:%d  set:%d",setMin,set);

        // 0xa2,'1','?'---询问
        // "{1!}"---空闲
        // "{1*}"---运行

        uint8_t cmd[] = {0xa2,set+1,'?'};
        while(!(LoRa_GetBeffer()[0] == '{' && LoRa_GetBeffer()[1] == set+'1' && LoRa_GetBeffer()[2] == '!' && LoRa_GetBeffer()[3] == '}')){
            LOG_E("%s",LoRa_GetBeffer());
            LoRa_Transmit(cmd, sizeof(cmd));
            rt_thread_delay(1000);
        }
        LoRa_GetBeffer()[0] = '\0';

        key_KA(0,1);
        robotArmRun.z = 140;  // 下去吸
        robotArm_actionGroup(0,&robotArmRun,1);
        robotArmRun.z = 260;  // 吸完上来
        robotArm_actionGroup(0,&robotArmRun,1);
        robotArmRun.y = 200;  // 回收一下
        robotArm_actionGroup(0,&robotArmRun,1);
        robotArmRun.z = 440;  // 抬高
        robotArm_actionGroup(0,&robotArmRun,1);

        rt_thread_delay(500);  // 确保吸到

        if(setMin <= 0 || setMin == INVALID_MAX_VALUE){
            rt_kprintf("识别错误\r\n",kind,set);
            //float ROBOT_DBG[3] = {0,200,230};
            robotArmRun = robotArm_assign(0,150,ARM2_LOOK_HIGH,ARM2_RUN_SPEED,1);  // 识别错误位置
            robotArm_actionGroup(0,&robotArmRun,1);
        }
        else {
            int flag = 0;  // 后续判断是否抓完
            switch(set){
            case 0:
                // 2号小车下货最终位置 -180,30,440
                robotArmRun = robotArm_assign(-180,30,440,ARM2_RUN_SPEED,1);  // 到2号放药位置
                robotArm_actionGroup(0,&robotArmRun,1);
                if(PharmacyData[set][kind-'A'] > 0){
                    PharmacyData[set][kind-'A'] -= 1;
                    LOG_D("药物%c还剩%d盒",kind,PharmacyData[set][kind-'A']);
                }
                if(FinishGoods[kind-'A'] > 0){
                    FinishGoods[kind-'A'] -= 1;
                    SumNum -= 1;
                    LOG_D("已经下货的%c药物还剩%d盒",kind,FinishGoods[kind-'A']);
                }

                for(int i=0;i<MEDICINE_NUM;i++){
                    if(PharmacyData[set][i] != 0)flag = 1;
                }
                if(flag == 0){
                    LOG_W("%d号房间的药物抓取完毕!!!",set);
                    uint8_t cmd[] = {0XA2,0X01,0X42};
                    LoRa_Transmit(cmd, 3);
                }
                break;
            case 1:
                // 1号小车下货最终位置 180,30,440
                robotArmRun = robotArm_assign(180,30,440,ARM2_RUN_SPEED,1);  // 到1号放药位置
                robotArm_actionGroup(0,&robotArmRun,1);
                if(PharmacyData[set][kind-'A'] > 0){
                    PharmacyData[set][kind-'A'] -= 1;
                    LOG_D("药物%c还剩%d盒",kind,PharmacyData[set][kind-'A']);
                }
                if(FinishGoods[kind-'A'] > 0){
                    FinishGoods[kind-'A'] -= 1;
                    SumNum -= 1;
                    LOG_D("已经下货的%c药物还剩%d盒",kind,FinishGoods[kind-'A']);
                }

                for(int i=0;i<MEDICINE_NUM;i++){
                    if(PharmacyData[set][i] != 0){
                        flag = 1;  // 判断是否抓取完毕
                    }
                }
                if(flag == 0){
                    LOG_W("%d号房间的药物抓取完毕!!!",set);
                    uint8_t cmd[] = {0XA2,0X02,0X41};
                    LoRa_Transmit(cmd, 3);
                }
                break;
            }

            pharmacy_prescription_show((int (*)[MEDICINE_NUM])PharmacyData);
            rt_kprintf("药物%c已经放在了%d药房\r\n",kind,set);
        }

        key_KA(0, 0);  // 放下药物
        yoloData.kind = '\0';   // 清除数据
        LOG_E("完成下货");

        rt_thread_delay(1000);  // 安全下货

        robotArmRun = robotArm_assign(0,200,440,ARM2_RUN_SPEED,1);  // 回一下
        robotArm_actionGroup(0,&robotArmRun,1);

        rt_sem_control(&rt_semaphore_pi, RT_IPC_CMD_RESET, RT_NULL); // 清除多余信号量

    }

}

// 下货机械臂线程
void thread_arm1(void * p){
    RobotArmRun_t robotArmRun = {0};

    LOG_D("Starting ARM1!!!");

    rt_thread_delay(3000);

    platform2D_init();

    LOG_D("Start ARM1 2D OK!!!");

    robotArm_init(1);

#if PLATFORM2D_POINT_DBG == 1

    robotArmRun = robotArm_assign(0,130,110,ARM1_RUN_SPEED,1);  // 等待抓药位置
    robotArm_actionGroup(1,&robotArmRun,1);
    setpMotor_power(2,1,0);
    setpMotor_power(2,2,0);
    float x_angle = 0;
    float y_angle = 0;
    while(1){
        x_angle = stepMotor_getAngle(2,1);
        y_angle = stepMotor_getAngle(2,2);
        LOG_E("X:%.2f  Y:%.2f",x_angle,y_angle);
        rt_thread_delay(100);
    }
#endif

#if ROBOT1_DEBUG == 1
    while(1){

        // 到1号放药位置
        robotArmRun = robotArm_assign(ROBOT_DBG[0],ROBOT_DBG[1],ROBOT_DBG[2],ARM2_RUN_SPEED,1);
        robotArm_actionGroup(1,&robotArmRun,1);

        rt_thread_delay(100);

    }
#endif

#if PALTFORM2D_DEBUG == 1
    int locat = 8;  // 位置
    while(1){
        robotArmRun = robotArm_assign(0,130,110,ARM1_RUN_SPEED,1);  // 等待抓药位置
        robotArm_actionGroup(1,&robotArmRun,1);
        platform2D_goList(locat%4,locat/4,50);  // 平台到指定位置

        while(1 == key_scan(1, 3)){  // 没有碰到盒子就往前伸
            if(robotArmRun.y >= 300){  // 非法距离警告
                LOG_W("距离非法");
                robotArmRun.y = 130;
            }
            robotArmRun.y += 10;
            robotArm_actionGroup(1,&robotArmRun,1);
            rt_thread_delay(10);
        }
        robotArmRun.y += 5;  // 确保吸紧
        robotArm_actionGroup(1,&robotArmRun,1);
        rt_thread_delay(10);

        key_KA(1, 1);  // 开吸
        rt_thread_delay(500);  // 确保吸住

        robotArmRun.y -= 30;  // 回收一下
        robotArm_actionGroup(1,&robotArmRun,1);
        rt_thread_delay(500);  // 确保吸住

        robotArmRun.z = 210;  // 举起来
        robotArm_actionGroup(1,&robotArmRun,1);

        robotArmRun = robotArm_assign(-170,20,210,ARM1_RUN_SPEED,1);  // 下药位置
        robotArm_actionGroup(1,&robotArmRun,1);

        key_KA(1, 0);  // 下药
        robotArmRun = robotArm_assign(-170,20,180,100,1);  // 抖一下
        robotArm_actionGroup(1,&robotArmRun,1);
        rt_thread_delay(500);  // 确保成功下药

        locat = locat >= 11 ? 0 : locat + 1; // 抓下一个位置

        rt_thread_delay(100);
    }
#endif

    while(1){
        // 开始下货，对下货的药品数量进行统计
        for(int i=0;i<MEDICINE_NUM;i++){
            SumNum = 0;
            for(int j=0;j<PHARMACY_NUM;j++){
                SumNum += PharmacyData[j][i];
            }
            if(SumNum != 0 && FinishGoods[i] < SumNum){
                while(FinishGoods[i] < SumNum){
                    {
#define QIAN_SHENG_WEI_ZHI 140
                        robotArmRun = robotArm_assign(0,QIAN_SHENG_WEI_ZHI,110,ARM1_RUN_SPEED,1);  // 等待抓药位置
                        robotArm_actionGroup(1,&robotArmRun,1);
                        platform2D_MedicineLoca(i);  // 平台到指定位置
                        rt_thread_delay(1000); //安稳到达指定位置
                        while(1 == key_scan(1, 3)){  // 没有碰到盒子就往前伸
                            if(robotArmRun.y >= EXTENSION_DISTANCE){  // 非法距离警告
                                LOG_W("距离非法");
                                robotArmRun.y = QIAN_SHENG_WEI_ZHI;
                            }
                            robotArmRun.y += 10;
                            robotArm_actionGroup(1,&robotArmRun,1);
                            rt_thread_delay(10);
                        }
//                        robotArmRun.y += 10;  // 确保吸紧
                        robotArm_actionGroup(1,&robotArmRun,1);
                        rt_thread_delay(10);

                        key_KA(1, 1);  // 开吸
                        rt_thread_delay(300);  // 确保吸住

                        robotArmRun.y -= 30;  // 回收一下
                        robotArm_actionGroup(1,&robotArmRun,1);
                        rt_thread_delay(500);  // 确保吸住

                        robotArmRun.z = 210;  // 举起来
                        robotArm_actionGroup(1,&robotArmRun,1);

                        robotArmRun = robotArm_assign(-170,20,210,ARM1_RUN_SPEED,1);  // 下药位置
                        robotArm_actionGroup(1,&robotArmRun,1);

                        key_KA(1, 0);  // 下药

                        robotArmRun = robotArm_assign(-170,20,180,100,1);  // 抖一下
                        robotArm_actionGroup(1,&robotArmRun,1);
                        rt_thread_delay(500);  // 确保成功下药

                    }
                    FinishGoods[i] += 1;
                    rt_kprintf("%c药品已下货\r\n",'A' + i);
                    LOG_D("%c类一共要抓%d盒药，已经抓了%d盒药",i+'A',SumNum,FinishGoods[i]);
                }
            }
        }
        robotArmRun = robotArm_assign(0,QIAN_SHENG_WEI_ZHI,110,ARM1_RUN_SPEED,1);  // 等待抓药位置
        robotArm_actionGroup(1,&robotArmRun,1);
        if(FinishGoods[0] == 0 && FinishGoods[1] == 0 && FinishGoods[2] == 0 && FinishGoods[3] == 0
        && FinishGoods[4] == 0 && FinishGoods[5] == 0 && FinishGoods[6] == 0 && FinishGoods[7] == 0
        && FinishGoods[8] == 0 && FinishGoods[9] == 0 && FinishGoods[10] == 0 && FinishGoods[11] == 0)
            platform2D_MedicineLoca(12); // 抓完回0
        rt_thread_delay(100);
    }
}

// LCD显示线程
void thread_lcd(void * p){
    LOG_D("Start LCD!!!");
    LCD_Clear();
    LCD_SetColor(LCD_WHITE);                    // 设置画笔颜色
    LCD_SetBackColor(LCD_BLACK);                 // 设置背景颜色
    LCD_SetDirection(Direction_V_Flip);            // 设置显示方向
    LCD_SetAsciiFont(&ASCII_Font24);
    char lcdBuffer[20] = "                    ";
    int line = 0;
    int oldPage = 0;
    while(1){
        line = 0;
        if(PageNum != oldPage)
            LCD_Clear();
        oldPage = PageNum;
#if ROBOT2_DEBUG == 1 || ROBOT1_DEBUG == 1
        if(2 == PageNum){
            sprintf(lcdBuffer,"X:%.0f      ",ROBOT_DBG[0]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer,"Y:%.0f       ",ROBOT_DBG[1]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer,"Z:%.0f     ",ROBOT_DBG[2]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer,"Change:%c",site + 'X');
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
        }
#endif
        if(0 == PageNum){
            // 显示药物统计信息
            sprintf(lcdBuffer,"Drug Statistics    ");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer,"Kind:              ");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," A B C D E F G H");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," I J K L M N O P");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);

            sprintf(lcdBuffer,"Pharmacy No.1:");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," %d %d %d %d %d %d %d %d"
                    ,PharmacyData[0][0],PharmacyData[0][1],PharmacyData[0][2],PharmacyData[0][3]
                    ,PharmacyData[0][4],PharmacyData[0][5],PharmacyData[0][6],PharmacyData[0][7]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," %d %d %d %d %d %d %d %d"
                    ,PharmacyData[0][8],PharmacyData[0][9],PharmacyData[0][10],PharmacyData[0][11]
                    ,PharmacyData[0][12],PharmacyData[0][13],PharmacyData[0][14],PharmacyData[0][15]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);

            sprintf(lcdBuffer,"Pharmacy No.2:");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," %d %d %d %d %d %d %d %d"
                    ,PharmacyData[1][0],PharmacyData[1][1],PharmacyData[1][2],PharmacyData[1][3]
                    ,PharmacyData[1][4],PharmacyData[1][5],PharmacyData[1][6],PharmacyData[1][7]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," %d %d %d %d %d %d %d %d"
                    ,PharmacyData[1][8],PharmacyData[1][9],PharmacyData[1][10],PharmacyData[1][11]
                    ,PharmacyData[1][12],PharmacyData[1][13],PharmacyData[1][14],PharmacyData[1][15]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
        }
        else if(1 == PageNum){
            // 显示药物数量信息
            line = 0;
            sprintf(lcdBuffer,"Drug Count         ");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer,"Kind:              ");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," A B C D E F G H");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," I J K L M N O P");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer,"Count:");
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," %d %d %d %d %d %d %d %d"
                    ,FinishGoods[0],FinishGoods[1],FinishGoods[2],FinishGoods[3]
                    ,FinishGoods[4],FinishGoods[5],FinishGoods[6],FinishGoods[7]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
            sprintf(lcdBuffer," %d %d %d %d %d %d %d %d"
                    ,FinishGoods[8],FinishGoods[9],FinishGoods[10],FinishGoods[11]
                    ,FinishGoods[12],FinishGoods[13],FinishGoods[14],FinishGoods[15]);
            LCD_DisplayString(0, 24*(line++),lcdBuffer);
        }
        rt_thread_delay(100);
    }
}

// LED控制线程
void thread_led(void * p){
    LOG_D("Start LED!!!");

    while(1){
        // LED闪烁
        led_set(0, 1);
        rt_thread_delay(100);
        led_set(0, 0);
        rt_thread_delay(100);
    }
}
